////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "Game.hpp"

#include <SFML/Graphics.hpp>

#include "DefaultGameImpl.hpp"
#include "DataManager.hpp"
#include "MessageDispatcher.hpp"
#include "../Entity/EntityManager.hpp"
#include "../Math/BoundingVolumes/BoundingBox.hpp"

#include <SmegTools/Debug/DebugNew.hpp>

namespace smeg {
    namespace core {

////////////////////////////////////////////////////////////
/// Constructor
////////////////////////////////////////////////////////////
Game::Game() :
    m_pGameImpl( NULL ),
    m_pRenderWindow( NULL ),
    m_GameClock(),
    m_LastFrameTime(sf::Time::Zero),
    m_ClearColor( sf::Color::Black )
{
}

////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
Game::~Game()
{
}

////////////////////////////////////////////////////////////
/// Init the game
////////////////////////////////////////////////////////////
void Game::Init(    const DefaultGameImpl& _GameImpl, 
                    sf::VideoMode _Mode, 
                    const char* _pTitle, 
                    unsigned _uFrameRateLimit,
                    sf::Uint32 _Style, 
                    const sf::ContextSettings& _Settings ) {
    if ( m_pRenderWindow ) return;

    srand((unsigned)time(NULL));

    m_pRenderWindow = new sf::RenderWindow( _Mode, _pTitle, _Style, _Settings );
    m_pRenderWindow->setFramerateLimit( _uFrameRateLimit );

    m_pGameImpl = _GameImpl.Clone();
    m_pGameImpl->Init( m_pRenderWindow );

    m_GameClock.restart();
    m_LastFrameTime = sf::Time::Zero;
}

void Game::Init(    const DefaultGameImpl& _GameImpl, 
                    sf::VideoMode _Mode, 
                    const char* _pTitle, 
                    const math::BoundingBox& _Region,
                    unsigned _uFrameRateLimit,
                    sf::Uint32 _Style, 
                    const sf::ContextSettings& _Settings ) {
    EntityManager::GetInstance()->SetupQuadTree( _Region );

    Init( _GameImpl, _Mode, _pTitle, _uFrameRateLimit, _Style, _Settings );
}

////////////////////////////////////////////////////////////
/// DeInit the game
////////////////////////////////////////////////////////////
void Game::DeInit() {
    m_pGameImpl->DeInit();

    delete m_pRenderWindow;
    m_pRenderWindow = NULL;
}

////////////////////////////////////////////////////////////
/// Game Loop
////////////////////////////////////////////////////////////
void Game::GameLoop() {
    sf::Event event;
    while ( m_pRenderWindow->isOpen() ) {
        if ( m_pRenderWindow->pollEvent( event ) ) {
            m_pGameImpl->ManageEvent( event );
        }
        
        m_pRenderWindow->clear( m_ClearColor );
        
        m_pGameImpl->Update( m_LastFrameTime.asSeconds() );
        m_pGameImpl->Render();

        m_pRenderWindow->display();

        m_LastFrameTime = m_GameClock.getElapsedTime();
        m_GameClock.restart();
    }
}

////////////////////////////////////////////////////////////
/// Change framerate
////////////////////////////////////////////////////////////
void Game::ChangeFramerateLimit( unsigned _uFrameRateLimit ) {
    m_pRenderWindow->setFramerateLimit( _uFrameRateLimit );
}
    
    } // namespace core
} // namespace smeg